//#include <iostream>
//#include <math.h>
//using namespace std;
//typedef long long ll;
//bool prime(ll n) {
//    if (n == 1) {
//        return false;
//    }
//    for (int i = 2; i <= sqrt(n); i++) {
//        if (n % i == 0) {
//            return false;
//        }
//    }
//    return true;
//}
//int main() {
//    int T;
//    cin >> T;
//    while (T--) {
//        ll a, b;
//        cin >> a >> b;
//        if ((a == 1 && prime(b)) || (b == 1 && prime(a))) {
//            cout << "YES" << endl;
//        }
//        else {
//            cout << "NO" << endl;
//        }
//    }
//    return 0;
//}


//#include <iostream>
//#include <algorithm>
//#include <vector>
//using namespace std;
//int n, k;
//int main() {
//    cin >> n >> k;
//    vector<int> v(n);
//    for (int i = 0; i < n; i++) {
//        cin >> v[i];
//    }
//    sort(v.begin(), v.end());
//    int left = 0;
//    int right = 0;
//    int ans = 0;
//    for (left = 0; left < n; left++)
//    {
//        while (right < n && (v[right] - v[left]) <= k)
//        {
//            right++;
//        }
//        ans = max(ans, right - left);
//        if (right == n) {
//            break;
//        }
//    }
//    cout << ans;
//    return 0;
//}

#include <iostream>
#include <algorithm>
using namespace std;
const int N = 1010;
int dp[N][N];
int main() {
    int n, m;
    cin >> n >> m;
    string s1, s2;
    cin >> s1 >> s2;
    for (int i = 1; i <= n; i++)
    {
        for (int j = 1; j <= m; j++)
        {
            if (s1[i - 1] == s2[j - 1]) {
                dp[i][j] = dp[i - 1][j - 1] + 1;
            }
            else {
                dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);
            }
        }
    }
    cout << dp[n][m];
    return 0;
}